<?php

require_once 'BancoDeDados.php';
require_once 'Objeto.php';

class Autor {

    private $cod_autor;
    private $nome;
    private $historico;
    private $assinatura;
    private $vinculado;
    private $objeto;

    public function setCod_autor(&$cod_autor) {
        $this->cod_autor = &$cod_autor;
    }

    public function &getCod_autor() {
        return $this->cod_autor;
    }

    public function setNome(&$nome) {
        $this->nome = &$nome;
    }

    public function &getNome() {
        return $this->nome;
    }

    public function setHistorico(&$historico) {
        $this->historico = &$historico;
    }

    public function &getHistorico() {
        return $this->historico;
    }

    public function setAssinatura(&$assinatura) {
        $this->assinatura = &$assinatura;
    }

    public function &getAssinatura() {
        return $this->assinatura;
    }

    public function &isVinculado() {
        return $this->vinculado;
    }

    private function setVinculado(&$vinculado) {
        $this->vinculado = &$vinculado;
    }

    /**
     *
     * @return Objeto
     */
    public function &getObjeto() {
        return $this->objeto;
    }

    public function setObjeto(Objeto &$objeto) {
        $this->objeto = &$objeto;
    }

    public function cadastrar() {
        if ($this->validar() != 1) {
            throw new Exception("Autor existente");
        }
        $banco = BancoDeDados::getInstance();
        $link = $banco->getLink();
        $stmt = $link->prepare('insert into autor (assinatura, historico, nome) values(?,?,?)');
        $result = $link->execute($stmt, array($this->assinatura, $this->historico, $this->nome));
        if (DB::isError($result)) {
            $link->rollBack();
            throw new Exception($result->getMessage());
        }
        $link->commit();
    }

    public function alterarCampo(&$campo_id, &$campo_valor) {
        if ($campo_id == 'nome' && $this->nome != $campo_valor) {
            $temp = &$this->nome;
            $this->nome = &$campo_valor;
            if ($this->validar() != 1) {
                throw new Exception("Autor existente |".$temp);
            }
        } else if ($campo_id == 'historico' && $this->historico != $campo_valor) {
            $temp = &$this->historico;
            $this->historico = &$campo_valor;
        } else if ($campo_id == 'assinatura' && $this->assinatura != $campo_valor) {
            $temp = &$this->assinatura;
            $this->assinatura = &$campo_valor;
        } else {
            throw new Exception('no_action');
        }
        $banco = BancoDeDados::getInstance();
        $link = $banco->getLink();
        $stmt = $link->prepare('update autor set ' . $campo_id . ' = ? where cod_autor = ?');
        $result = $link->execute($stmt, array($campo_valor, $this->cod_autor));
        if (DB::isError($result)) {
            $link->rollBack();
            throw new Exception($result->getMessage()." |".$temp);
        }
        $link->commit();
    }

    public function excluir() {
        $banco = BancoDeDados::getInstance();
        $link = $banco->getLink();
        $stmt = $link->prepare('delete from autor where cod_autor = ?');
        $result = $link->execute($stmt, array($this->cod_autor));
        if (DB::isError($result)) {
            $link->rollBack();
            throw new Exception($result->getMessage());
        }
        $link->commit();
    }

    public static function listar() {
        $banco = BancoDeDados::getInstance();
        $result = $banco->getLink()->query('select * from autor');
        if (DB::isError($result)) {
            throw new Exception($result->getMessage());
        }
        $resultado = array();
        while ($result->fetchInto($row)) {
            $autor = new Autor();
            $autor->setCod_autor($row['cod_autor']);
            $autor->setAssinatura($row['assinatura']);
            $autor->setHistorico($row['historico']);
            $autor->setNome($row['nome']);
            $autor->setVinculado($autor->verificarVinculacao());
            $resultado[] = &$autor;
            unset($autor);
        }
        return $resultado;
    }

    public static function &consultar($cod_autor) {
        $banco = BancoDeDados::getInstance();
        $result = $banco->getLink()->query('select * from autor where cod_autor = ?', array($cod_autor));
        if (DB::isError($result)) {
            throw new Exception($result->getMessage());
        }
        if ($result->numRows() == 0) {
            throw new Exception("Autor inexistente");
        } elseif ($result->numRows() > 1) {
            throw new Exception("Mais de um Autor com o mesmo identificador, informe ao administrador");
        }
        $result->fetchInto($row);
        $autor = new Autor();
        $autor->setCod_autor($row['cod_autor']);
        $autor->setAssinatura($row['assinatura']);
        $autor->setHistorico($row['historico']);
        $autor->setNome($row['nome']);
        return $autor;
    }

    public static function listarPorObjeto(Objeto &$objeto) {
        $banco = BancoDeDados::getInstance();
        $result = $banco->getLink()->query('SELECT autor.cod_autor, autor.nome, autor.historico, autor.assinatura FROM public.objeto_autor, public.autor WHERE autor.cod_autor = objeto_autor.cod_autor and cod_interno = ?', array($objeto->getCod_interno()));
        if (DB::isError($result)) {
            throw new Exception($result->getMessage());
        }
        $resultado = array();
        while ($result->fetchInto($row)) {
            $autor = new Autor();
            $autor->setCod_autor($row['cod_autor']);
            $autor->setAssinatura($row['assinatura']);
            $autor->setHistorico($row['historico']);
            $autor->setNome($row['nome']);
            $autor->setObjeto($objeto);
            $resultado[$row['cod_autor']] = &$autor;
            unset($autor);
        }
        return $resultado;
    }

    private function validar() {
        $banco = BancoDeDados::getInstance();
        $result = $banco->getLink()->query('select cod_autor from autor where nome = ?', array($this->nome));
        if (DB::isError($result)) {
            throw new Exception($result->getMessage());
        }
        if ($result->numRows() > 0) {
            return 0;
        }
        return 1;
    }

    private function verificarVinculacao() {
        $banco = BancoDeDados::getInstance();
        $result = $banco->getLink()->query('select cod_autor from objeto_autor where cod_autor = ?', array($this->cod_autor));
        if (DB::isError($result)) {
            throw new Exception($result->getMessage());
        }
        if ($result->numRows() > 0) {
            return 1;
        }
        return 0;
    }

    public function cadastrarObjeto() {
        $banco = BancoDeDados::getInstance();
        $result = $banco->getLink()->query('select cod_autor from objeto_autor where cod_autor = ? and cod_interno = ?', array($this->cod_autor, $this->objeto->getCod_interno()));
        if (DB::isError($result)) {
            throw new Exception($result->getMessage());
        }
        if ($result->numRows() > 0) {
            throw new Exception('Autor existente');
        }
        $banco = BancoDeDados::getInstance();
        $link = $banco->getLink();
        $stmt = $link->prepare('insert into objeto_autor (cod_interno, cod_autor) values(?,?)');
        $result = $link->execute($stmt, array($this->objeto->getCod_interno(), $this->cod_autor));
        if (DB::isError($result)) {
            $link->rollBack();
            throw new Exception($result->getMessage());
        }
        $link->commit();
    }

    public function excluirObjeto() {
        $banco = BancoDeDados::getInstance();
        $link = $banco->getLink();
        $stmt = $link->prepare('delete from objeto_autor where cod_autor = ? and cod_interno = ?');
        $result = $link->execute($stmt, array($this->cod_autor, $this->objeto->getCod_interno()));
        if (DB::isError($result)) {
            $link->rollBack();
            throw new Exception($result->getMessage());
        }
        $link->commit();
    }

}
?>